package com.zj.study.controller;

import com.zj.study.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;


/**
 * @author ZhaoJiu
 * @since: 2021/7/19 10:24
 * @desc:
 */
@Slf4j
@RestController
public class HelloController {

    private static final WebClient client =
            WebClient.create("http://localhost:8080");

    /**
     * 测试WebClient调用
     *
     * @return 响应数据
     */
    @GetMapping("/get")
    public Mono<String> getStr() {
        return client
                .get()
                .uri("/hello")
                .retrieve()
                .bodyToMono(String.class)
                .doOnError(e -> {
                    log.error("服务出现异常，异常信息: {}", e.getMessage());
                });
    }

    /**
     * 测试WebClient调用数据库操作
     *
     * @return 响应数据
     */
    @GetMapping("/getUsers")
    public Flux<User> getUsers() {
        return client
                .get()
                .uri("/user/list")
                .retrieve()
                .bodyToFlux(User.class)
                .doOnError(e -> {
                    log.error("服务出现异常，异常信息: {}", e.getMessage());
                });
    }

    @GetMapping("/hello")
    public Mono<String> hello() {
        return Mono.just("Welcome to reactive world ~");
    }

    /**
     * mono
     *
     * @return
     */
    @GetMapping("mono")
    public Mono<Object> mono() {
        return Mono.create(monoSink -> {
            log.info("创建 Mono");
            monoSink.success("hello webflux");
        }).doOnSubscribe(
                subscription -> log.info("{}", subscription)
        ).doOnNext(o -> {
                    //当订阅者收到数据时，改方法会调用
                log.info("{}", o);
                });
    }

    /**
     * Flux 可以发送多个数据
     *
     * @return 响应数据
     */
    @GetMapping("flux")
    public Flux<String> flux() {
        return Flux.just("hello ", "webflux ", "spring", "boot");
    }

}
